package com.tanovo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tanovo.bo.MenuQueryBo;
import com.tanovo.bo.ResourceCheckBo;
import com.tanovo.bo.UserCore;
import com.tanovo.config.UserInfoContext;
import com.tanovo.constant.ResourcesConstant;
import com.tanovo.domain.*;
import com.tanovo.exception.ServiceException;
import com.tanovo.mapper.ResourcesMapper;
import com.tanovo.mapper.RoleResourceMapper;
import com.tanovo.service.IResourcesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ResourcesServiceImpl implements IResourcesService {

    @Autowired
    private ResourcesMapper resourcesMapper;

    @Autowired
    private RoleResourceMapper roleResourceMapper;

    @Override
    public List<Resources> getListByRole(Role role) {
        List<Resources> resourcesList = resourcesMapper.getListByRole(role);
        return resourcesList;
    }

    @Override
    public void addResource(Resources resource) {
        if (StringUtils.isNotBlank(resource.getPath()) && resource.getPath().contains("*")) {
            log.error("添加资源错误：{}", JSONObject.toJSONString(resource));
            throw new ServiceException("不可以使用通配符'*'");
        }
        resource.setDelFlag(0);
        resource.setEnable(1);
        resource.setClientId(UserInfoContext.getUser().getClientId());
        resource.setCompanyId(UserInfoContext.getUser().getCompanyId());
        resource.setPath(resource.getPath().trim());
        resource.setDelFlag(0);
        resource.setCreateTime(new Date());
        resource.setUpdateTime(new Date());
        resource.setUpdateBy(UserInfoContext.getUser().getId().toString());
        resource.setCreateBy(UserInfoContext.getUser().getId().toString());
        resourcesMapper.insert(resource);
    }

    @Override
    public void delete(Integer resourceId) {
        ResourcesExample resourcesExample = new ResourcesExample();
        resourcesExample.createCriteria()
                .andIdEqualTo(resourceId)
                .andClientIdEqualTo(UserInfoContext.getUser().getClientId());
        Resources resources = new Resources();
        resources.setId(resourceId);
        resources.setDelFlag(1);
        resources.setUpdateTime(new Date());
        resources.setUpdateBy(UserInfoContext.getUser().getId().toString());
        resourcesMapper.updateByExampleSelective(resources, resourcesExample);
        //删除角色资源关联表
        RoleResource roleResource = new RoleResource();
        roleResource.setDelFlag(1);
        RoleResourceExample example = new RoleResourceExample();
        example.createCriteria()
                .andResourceIdEqualTo(resourceId)
                .andClientIdEqualTo(UserInfoContext.getUser().getClientId());
        roleResourceMapper.updateByExample(roleResource, example);
    }

    @Override
    public void editResource(Resources resource) {
        ResourcesExample resourcesExample = new ResourcesExample();
        resourcesExample.createCriteria()
                .andIdEqualTo(resource.getId())
                .andClientIdEqualTo(UserInfoContext.getUser().getClientId());
        resource.setUpdateTime(new Date());
        resource.setUpdateBy(UserInfoContext.getUser().getId().toString());
        resource.setPath(resource.getPath().trim());
        resourcesMapper.updateByExampleSelective(resource, resourcesExample);
    }


    @Override
    public Resources getDetail(Integer resourceId) {
        ResourcesExample resourcesExample = new ResourcesExample();
        resourcesExample.createCriteria()
                .andIdEqualTo(resourceId)
                .andClientIdEqualTo(UserInfoContext.getUser().getClientId())
                .andDelFlagEqualTo(0);
        List<Resources> resources = resourcesMapper.selectByExample(resourcesExample);
        if (!CollectionUtils.isEmpty(resources)) {
            return resources.get(0);
        } else {
            return null;
        }
    }


    @Override
    public List<Resources> getResourceByParentId(Integer parentId,String clientId,Integer userId) {
        List<Resources> resourcesList = resourcesMapper.getByParentId(parentId, clientId,userId);
        for (Resources re : resourcesList) {
            Integer count = resourcesMapper.hasChildren(re.getId());
            if (count != null && count > 0) {
                re.setHasChildren(true);
            }
        }
        return resourcesList;
    }

    @Override
    public List<Resources> getCurrentUserList(Integer userId) {
        //判断是不是超级权限 如果是 给出最高权限
        UserCore user = UserInfoContext.getUser();
        List<Resources> list = new ArrayList<>();
        if (userId == ResourcesConstant.SUPER_ADMIN_ID) {
            Resources resources = new Resources();
            resources.setPath("/**");
            list.add(resources);
            return list;
        }
        list = resourcesMapper.getCurrentUserList(userId, user.getClientId());
        return list;
    }

    @Override
    public List<Resources> getCurrentSystemMenuList(Integer parentId) {
        List<String> clientList = new ArrayList<>();
        clientList.add("tanovo");
        clientList.add(UserInfoContext.getUser().getClientId());
        ResourcesExample example = new ResourcesExample();
        example.createCriteria()
                .andParentIdEqualTo(parentId)
                .andDelFlagEqualTo(0)
                .andClientIdIn(clientList)
                .andResourceTypeEqualTo(ResourcesConstant.RESOURCE_TYPE_MENU);//菜单类型
        List<Resources> resourcesList = resourcesMapper.selectByExample(example);
        for (Resources resources : resourcesList) {
            resources.setChildrenList(this.getCurrentSystemMenuList(resources.getId()));
        }
        return resourcesList;
    }


    @Override
    public List<Resources> getCheckedList(Integer parentId, Integer roleId,String clientId,Integer userId) {
        List<Resources> resourcesList = this.getResourceByParentId(parentId,clientId,userId);
        if (!CollectionUtils.isEmpty(resourcesList)) {
            Role role = new Role();
            role.setId(roleId);
            List<Resources> roleResourceList = this.getListByRole(role);
            if (!CollectionUtils.isEmpty(roleResourceList)) {
                for (Resources roleSources : roleResourceList) {
                    for (Resources resources : resourcesList) {
                        if (roleSources.getId().intValue() == resources.getId().intValue()) {
                            resources.setChecked(true);
                        }
                    }
                }
            }
        }
        return resourcesList;
    }

    @Transactional
    @Override
    public void deleteList(List<Integer> resourceIdList) {
        for (Integer resourceId : resourceIdList) {
            this.delete(resourceId);
        }
    }


    @Override
    public ResourceCheckBo checkPath(String uri) {
        List<Resources> resourcesList = this.getCurrentUserList(UserInfoContext.getUser().getId());
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        ResourceCheckBo bo = new ResourceCheckBo();
        boolean match = false;
        Integer enable = 0;
        for (Resources re : resourcesList) {
            match = antPathMatcher.match(re.getPath(), uri);
            if (match) {
                enable = re.getEnable();
                break;
            }
        }
        if (match && enable == 1) {
            bo.setNumberCode(1);
            bo.setMessage("有权限");
        }
        if (match && enable == 0) {
            bo.setNumberCode(0);
            bo.setMessage("权限被禁用");
        }
        if (!match) {
            bo.setNumberCode(-1);
            bo.setMessage("没有权限");
        }
        return bo;
    }


    @Override
    public List<Resources> getCurrentUserMenuList(MenuQueryBo queryBo) {
        List<Resources> topList = resourcesMapper.getCurrentUserMenuList(queryBo);
        for (Resources resources : topList) {
            MenuQueryBo childQuery = new MenuQueryBo();
            childQuery.setParentId(resources.getId());
            childQuery.setClientId(queryBo.getClientId());
            childQuery.setUserId(queryBo.getUserId());
            childQuery.setCompanyId(queryBo.getCompanyId());
            resources.setChildrenList(this.getCurrentUserMenuList(childQuery));
        }
        return topList;
    }

    @Override
    public List<Resources> getResourceByCompanyIdAndClientId(String clientId, Integer companyId) {
        ResourcesExample example = new ResourcesExample();
        example.createCriteria()
                .andDelFlagEqualTo(0)
                .andClientIdEqualTo(clientId)
                .andCompanyIdEqualTo(companyId);
        List<Resources> list = resourcesMapper.selectByExample(example);
        return list;
    }


    @Override
    public void giveAdminResources(Role admin) {
        List<Resources> appAdminResources = this.getAppAdminResources();
        Date date = new Date();
        for (Resources re : appAdminResources) {
            RoleResource roleResource = new RoleResource();
            roleResource.setResourceId(re.getId());
            roleResource.setRoleId(admin.getId());
            roleResource.setDelFlag(0);
            roleResource.setCreateBy(UserInfoContext.getUser().getId().toString());
            roleResource.setUpdateTime(date);
            roleResource.setCompanyId(UserInfoContext.getUser().getCompanyId());
            roleResource.setClientId(UserInfoContext.getUser().getClientId());
            roleResourceMapper.insertSelective(roleResource);
        }
    }

    @Override
    public List<Resources> getAppAdminResources() {
        return resourcesMapper.getAppAdminResources();
    }

    @Override
    public List<Resources> adminResourceList() {

        return null;
    }

    @Override
    public List<Resources> getAppResourceByParentId(int parentId, String clientId, Integer userId) {
        List<Resources> list = resourcesMapper.getAppResourceByParentId(parentId,clientId,userId);
        for (Resources re : list) {
            Integer count = resourcesMapper.hasChildren(re.getId());
            if (count != null && count > 0) {
                re.setHasChildren(true);
            }
        }
        return list;
    }
}
